#!/usr/bin/env bash

[  -f "$HOME/myconfig" ] && . $HOME/myconfig 
[ "${_XT:-}" ] && {
    set -o xtrace
}
declare -A usage
_info () {
    echo -e "\e[32m$@\e[39m"
}
_warn () {
    echo -e "\e[93m$@\e[39m"
}
_err () {
    echo -e "\e[31m$@\e[39m"
}
_i() {
    echo -e "\e[32m$@\e[39m"
}
_w() {
    echo -e "\e[93m$@\e[39m"
}
_e() {
    echo -e "\e[31m$@\e[39m"
}
desc="g开头获取,l日志"
usage[ga]="获取所有命名空间的POD,SVC,DEPLOYMENT"
usage[getNs]="获取缩写的命名空间"
usage[v]="获得k8s所有版本"
usage[i]="安装k8s"
usage[gt]="生成 k8s dashboard token"
usage[dtk]="k8s init token for dashboard"
usage[gp]="获得某个命名空间的所有pods 1.ns"
usage[gn]="打印所有的命名空间"
usage[gs]="获得某个命名空间的所有services 1.ns"
usage[gd]="获得某个命名空间的所有deployments 1.ns"
usage[gpa]="获取所有命名空间的pods"
usage[gda]="获取所有命名空间的svc"
usage[l]="默认100条logs并跟踪日志 [1.条数(100等) 2.命名空间的关键词 3.pod的关键词]"
usage[lt]="默认5分钟并跟踪日志 [1.列出从时间(5m/5h等) 2.命名空间的关键词 3.pod的关键词]"
usage[e]="编辑resource编排信息 1.res(pods,services,deployments) 2resName [3 namespace:default]"
usage[ep]="编辑pod信息 1.resName [2 namespace:default] "
usage[ed]="编辑deployment 信息 1.resName [2 namespace:default]\n"
usage[es]="编辑service 信息 1.resName [2 namespace:default]"
usage[rm]="删除pod/service等 delete后参数"
usage[i]="resource集群相关的信息 1.resType(pods,services,deployments) 2resName [3 namespace:default]"
usage[ip]="获得的是pod 相关的信息 1.resName [2 namespace:default]"
usage[is]="describe service 相关的信息 1.resName [2 namespace:default]"
usage[id]="获得的是deployment相关的信息 1.resName [2 namespace:default]"
usage[cr]="create创建资源 1.json file/yaml file"
usage[ru]="rollUpdate 开始k8s滚动更新 1.yamlFile 2resourceName"
usage[ra]="重启本节点的apiseerver,controller-manager,proxy,kubelet,scheduler"
usage[pa]="停止本节点的apiseerver,controller-manager,proxy,kubelet,scheduler"
usage[h]="helps"
usage[lp]="打印pod的日志 1pod名字 [2 -f追踪] ...其他额外参数(-c nginx pod里的容器)"
usage[dk8s]="delete/uninstall k8s"
usage[ih]="install helm"
usage[dtk]="get k8s init token for dashboard"
usage[s]="查看k8s基础信息和统计 1. 具体某pod(关键词)"
usage[d]="k8s的debug工具 [1.命名空间的关键词 2.pod的关键词 3.image的关键词]"

s(){
 
    local pod=$1
    if [ ! -z $pod ];then
        kubectl top pod -A|grep $pod
    else
        kubectl top pod -A
    fi
 
    kubectl top node
    kubectl cluster-info
    v
}
getNs(){
    declare -A kubeNs
    local ns=${1:-d}
    kubeNs=([d]='default' [p]='kube-public' [s]='kube-system')
    if [ -z "${kubeNs[$ns]}" ];then
        echo $ns
    else
        echo "${kubeNs[$ns]}"
    fi  
}
gp(){
    local help="获得某个命名空间的所有pods 1ns"
    _info "$help"
    getNamespace $1
    local ns=$CUR_NS
    echo "get ns $ns"
    set -x
    kubectl get pods -n $ns
    set +x
}
gn(){
    local help="打印所有的命名空间"
    _i "$help"
    kubectl get namespaces
}

ga(){
    _i "POD"
    kubectl get -A pod
    _i SERVICE
    kubectl get -A svc
    _i DEPLOYMENT
    kubectl get -A deployment
}
gs(){
        local help="获得某个命名空间的所有services 1ns"
    _i "$help"

    getNamespace $1
    local ns=$CUR_NS
    kubectl -n $ns get services 
}
v(){

    _i "node version"
    kubectl get nodes
    _i "k8s version"
    kubectl version
    _i "k8s client version"
    kubectl version --client
}
i(){
    local help="安装k8s"
    _i "$help"
    local version=${1:-3.3.1}
    echo "install 3.3.1 with k8s 1.24"
    wget https://github.com/easzlab/kubeasz/releases/download/$version/ezdown
    chmod +x ./ezdown
    ./ezdown -D
    ./ezdown -S
    docker exec -it kubeasz ezctl start-aio
    bash
    kubectl version --client
    kubectl get nodes --all-namespaces
}
gt(){
    local help="generate k8s dashboard token"
    _i "$help"
    local user=${1:-'admin-user'}
    local dashboardNs=${2:-'kube-system'}
    local dashboardNs=kube-system
    kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: $user
  namespace: $dashboardNs
EOF
    kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: $user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: $user
  namespace: $dashboardNs
EOF

    kubectl -n $dashboardNs create token $user
}

gd(){
     local help="获得某个命名空间的所有deployments 1ns"
     _i "$help"
    
    getNamespace $1
    local ns=$CUR_NS
    kubectl -n $ns get deployments
}
gpa(){
    kubectl get -A pods
}

gsa(){
    kubectl get -A services 
}
gda(){
    kubectl get -A deployments
}
l(){
    NO_SH_PROMPT=1 getNsPodSh $@
    _i "$ns $pod"
    local num=${1:-100}
    set -x
    kubectl logs --tail=$num -f $CUR_POD -n $CUR_NS
    set +x
}
lt(){
     NO_SH_PROMPT=1 getNsPodSh $@
    _i "$ns $pod"
    local time=${1:-5m}
    kubectl logs  $CUR_POD --since=$time -n $CUR_NS
}
e(){
     local help="1resType(1:pods,2:services,3:deployments) 2resName [3 namespace:default]\n编辑r esource编排 信息\n"
    [ $# -lt 2 ] && _e "$help"
  
    getNamespace $3
    local ns=$CUR_NS
    local resType=$1
    local resName=$2
    getNamespace $ns

    declare -A types
    types=([1]=Pod [2]=Service [3]=Deployment)
    if [ -z "$resType" ];then
        _info "选择1: Pod 2:Service 3:Deployment"
        read resType
    fi
    local chooseType="${types[$resType]}"
    [  -z "$chooseType" ] && _err "不存在的类型" && return

    "get${chooseType}" $resName

    kubectl  edit "${types[$resType]}" -o yaml -n $ns
}
ep(){
    local help="1resName [2 namespace:default]\n编辑pod 信息\n"
    getNamespace $@
    getPod $@
    kubectl edit -n $CUR_NS pod $CUR_POD -o yaml
}
ed(){
      local help="1resName [2 namespace:default]\n编辑deployment 信息\n"
      local name=$1
    [ $# -lt 1 ] && echo -e "$help" && return
     local foundNs=$(gda|grep $name|grep -v "grep "|head -1|awk '{print $1}')
    local ns=${2:-$foundNs}
     kubectl edit deployment $name  -o yaml -n $ns
}
es(){
      local help="1resName [2 namespace:default]\n编辑service 信息\n"
    [ $# -lt 1 ] && echo -e "$help" && return
    local name=$1
    local foundNs=$(gsa|grep $name|grep -v "grep "|head -1|awk '{print $1}')
    local ns=${2:-$foundNs}
    _i "$ns $name"
    kubectl edit  service $name -o yaml -n $ns 
}
rm(){
     local help="删除pod/service等"
     _i "$help"
     kubectl delete "$@"
}
usage[ex]="1podName [2 shell:bash]\n登录pod\n"
usage[g]="导航或者输入关键词进入某个pod 1.命名空间 2.pod [3.shell(bash/sh/ash):bash]"
getNamespace(){
    local namespace=$1
    local choices=""
    local defaultNs=$(getNs d)
    local ns=""
    choices="$(gn|nl -n ln)"
    [ -z "$namespace" ] && {
        _info "$choices"
        _info "选择命令空间:"
        read namespace
        namespace="^$namespace "
    }
    [ ! -z "$namespace" ] && {
        ns="$(echo -e "$choices"|grep "$namespace"|awk '{print $2}')"
    }
    _info "选择namespace是: $ns"
    ns="${ns:-$defaultNs}"
    CUR_NS=$ns
}
getService(){
    local service=$1
    local ns=${2:-$CUR_NS}
    choices="$(gs $ns|nl -n ln)"
    [ -z "$service" ] && {
        _info "$choices"
        _info "选择Pod:"
        read service
        service="^$service "
    }
    local serviceName=""
    [ ! -z "$pod" ] && {

        serviceName="$(echo -e "$choices"|grep "$service"|awk '{print $2}')"
    }
    CUR_SERVICE=$serviceName
    _info "选择service是: $serviceName"
}
getDeployment(){
    local deployment=$1
    local ns=${2:-$CUR_NS}
    choices="$(gd $ns|nl -n ln)"
    [ -z "$deployment" ] && {
        _info "$choices"
        _info "选择Deployment:"
        read deployment
        deployment="^$deployment "
    }
    local deploymentName=""
    [ ! -z "$pod" ] && {
        deploymentName="$(echo -e "$choices"|grep "$deployment"|awk '{print $2}')"
    }
    CUR_DEPLOYMENT=$deploymentName
    _info "选择deployment是: $deploymentName"
}
getPod(){
    local pod=$1
    local ns=${2:-$CUR_NS}
    choices="$(gp $ns|nl -n ln)"
    [ -z "$pod" ] && {
        _info "$choices"
        _info "选择Pod:"
        read pod
        pod="^$pod "
    }
    local podName=""
    [ ! -z "$pod" ] && {

        podName="$(echo -e "$choices"|grep "$pod"|awk '{print $2}')"
    }
    CUR_POD=$podName
    _info "选择POD是: $podName"
}
getNsPodSh(){
    local namespace=$1
    local pod=$2
    local shell=$3
    _info "namespace:$namespace,pod:$pod,shell:$shell"
    
    getNamespace $namespace
    getPod $pod
    if [  -z "$NO_SH_PROMPT" ];then
        [ -z "$shell" ] && {
            _info "输入Shell名称(zsh/bash/sh/ash),默认bash:"
            _info "选择Shell:"
            read shell
        }
        NO_SH_PROMPT=""
    fi
    
    shell=${shell:-bash}
    CUR_SH=$shell
   

    echo "$ns $podName $shell"
}

kdebug(){
    local ns=$1
    local pod=$2
    local DEBUG_IMAGE=registry.cn-beijing.aliyuncs.com/outerimgs/net-tools
    local DEBUG_IMAGE=digitalcity-registry.cn-beijing.cr.aliyuncs.com/base/common/k8s/java-debug:v1.0
    local image=${3:-$DEBUG_IMAGE}

# if [ -z $3 ]; then
#   DEBUG_IMAGE=registry.cn-beijing.aliyuncs.com/outerimgs/net-tools
# elif [ "$3" = "net-tools" ]; then
#   DEBUG_IMAGE=registry.cn-beijing.aliyuncs.com/outerimgs/net-tools
# elif [ "$3" = "httpdump" ]; then
#   DEBUG_IMAGE=registry.cn-beijing.aliyuncs.com/outerimgs/httpdump
# elif [ "$3" = "tshark" ]; then
#   DEBUG_IMAGE=registry.cn-beijing.aliyuncs.com/outerimgs/tshark:4.0.3
# else
#   DEBUG_IMAGE=$3
# fi
    k8sdebug $pod --agent-image=registry.cn-beijing.aliyuncs.com/outerimgs/k8s-debug-agent:v0.1.1 --image=$image --namespace=$ns
}
ex(){
    [ $# -lt 1 ] && _i "${usage[ex]}" && return
    local sh=${3:-bash}
    local name=$2
    
   getNamespace $1
    local ns=$CUR_NS        
    kubectl exec -it  -n $ns $name -- $sh
}
g(){
    getNsPodSh $@
    ex $CUR_NS $CUR_POD $CUR_SH
}
d(){
   NO_SH_PROMPT=1 getNsPodSh $@
   kdebug $CUR_NS $CUR_POD
}
i(){
    local help="1resType(pods,services,deployments) 2resName [3 namespace:default]\n获得的是resource集群相关的信息\n" 
    [ $# -lt 1 ] && _i "$help" && return
   
    getNamespace $3
    local ns=$CUR_NS
    local type=$1
    local name=$2
    kubectl -n $ns describe $type $name
}
ip(){
    NO_SH_PROMPT=1 getNsPodSh  $@ 
    kubectl -n $CUR_NS describe pods $CUR_POD
}
is(){
    local help="1resName [2 namespace:default]\n describe的是service 相关的信息\n" 
    _i "$help" 

    local name=$1
    
    local foundNs=$(gsa|grep $name|grep -v "grep "|head -1|awk '{print $1}')

    local ns=${2:-$foundNs}
    _i "$ns $name"
    kubectl -n $ns describe services $name
}
id(){
     local help="1resName [2 namespace:default]\n获得的是deployment相关的信息\n"
    _i "$help" 
    local name=$1
    local foundNs=$(gda|grep $name|grep -v "grep "|head -1|awk '{print $1}')

    local ns=${2:-$foundNs}
    _i "$ns $name"
    kubectl -n $ns describe deployments $name
}
cr(){
     local help="1.json file/yaml file 创建资源\n" 
    [ $# -lt 1 ] && _e "$help"  && return;
    local yamlorJsonFilePath=$1
    kubectl create -f {$yamlorJsonFilePath}

}
ru(){
    local help="开始k8s滚动更新 1yamlFile 2resourceName"
    [ $# -lt 2 ] && _i "$help"  && return;
    local yamlFile=$1
    local resourceName=$2
    kubectl rolling-update {$resourceName} -f {$yamlFile}

}
ra(){
    local srvs="kube-apiserver   kube-controller-manager  kube-proxy  kube-scheduler kubelet"
    _info "即将停止 $srvs,3秒后无应答,默认自动停止(y/n)"
    read -t 5 stop 
    if [ "$stop" != "n" ];then
        for srv in $srvs;do
            service $srv restart
        done
    fi
}
sa(){
    local help="开始k8s所有组件"
    _i "$help"
  
    srvs="kube-apiserver   kube-controller-manager  kube-proxy  kube-scheduler kubelet"
    for srv in $srvs;do
         service $srv start
    done
}
pa(){
    local help="停止k8s所有组件"
     _i "$help"
    srvs="kube-apiserver   kube-controller-manager  kube-proxy  kube-scheduler kubelet"
    for srv in $srvs;do
         service $srv stop
    done
}
h(){
    cat - <<EOF
help 
trubleshooting
https://kubernetes.io/docs/tasks/debug/debug-application/
标签写法 -lapp=xxx -c容器名字
#允许expired serving certificate
--insecure-skip-tls-verify-backend
--selector app=name
# Return snapshot logs from container nginx-1 of a deployment named nginx

kubectl logs deployment/nginx -c nginx-1 
EOF
}
lp(){
    local help="打印pod的日志 1pod名字 [2 -f追踪] ...其他额外参数(-c nginx pod里的容器)"
    _i "$help"
   local choice=$1
   local flag=${2:-""}
   local pods=$(kubectl get -A pods)
   
    echo -e "$pods"


    if [ -z $choice ];then
        _i "choice:"
        read choice 
    fi

 [ ! -z "$(echo $choice |grep -E '^[0-9a-zA-Z\-_]+$')" ] && choice="$choice"
 choice=$(echo -e "$pods"|grep "$choice"|head -1)
 local ns=$(echo $choice|awk '{print $1}')
 local pod=$(echo $choice|awk '{print $2}')
 set -x
 [ ! -z "$3" ] && {
     shift
     shift 
 }
 kubectl logs $flag  -n $ns $pod "$@"
 set +x
}
dk8s(){
    local help="delete/uninstall k8s"
    docker exec -it kubeasz ezctl setup default all
    _i "删除所有的k8s的容器"
    read -p "确定吗?(y/n)" n
    [ "$n" = "y" ] && {
         docker ps -a |grep -i k8s_|awk '{print $1}'|xargs docker rm
    }
    _i "重启以便删除所有的节点" 
}
ih(){
    local help="install helm"
    _i "$help"
    wget -c https://repo.huaweicloud.com/helm/v3.7.2/helm-v3.7.2-linux-amd64.tar.gz helm-v3.7.2-linux-amd64.tar.gz

    tar xvzf helm-v3.7.2-linux-amd64.tar.gz

    mv linux-amd64/helm /usr/local/bin
}
dtk(){
    local help="k8s init token for dashboard"
    _i "$help"
    kubectl describe secret -n=kube-system|grep token
}
# for func in _w _e i_k8s d_k8s kdtk2 gtoken kgp2 kga2 kgs2 kgd2 kga2 kgp3 kgs3 kgd3 kgn2 klp2  klo2 klot2 ked2 kedp2 kedd2 keds2 krm2 kex2 kde2 kdep2 kdes2 kded2 kcr2 kru2 kra ksa kv9 kpa  kuh2 ihelm;do
# if [ "$(type -t $func)" = "function" ];then
# export -f $func
# else
# _e "$func not exists"
# fi
# done

usage['sn']="获取namespace所有pod的流量 [1. namespace]"
sn(){
    getNamespace $@
    kubeshark tap -n $CUR_NS  
}
usage['sp']="获取pod的流量 [1.ns 2.pod1*|pod2*]"
sp(){
    getNamespace $@
    local ns="$1"
    local pods=""
    [ ! -z "$ns" ] && {
        pods="$2"
    }
    [ -z "$pods" ] && {
        getPod 
        pods=$CUR_POD
    }
    kubeshark tap -n $CUR_NS $pods 
}

usage['_']="search usage"
usage['__']="search script content"
usage["_sr"]="查看源代码 1.file 2.func"

_(){
local kw=$1
 rg "usage\[.*$kw" $0
}
__(){
 rg "$@" $0 
}
_sr(){

     local func=$1
     rg --multiline --multiline-dotall  -e  "$func\(\)\{.*?\n}\n" $0
}







func=$1
isHelp=$2
MY_DIR=$HOME/my

    if [ "$func" = "-" -o -z "$func" ];then
_info "$desc"    
echo -e "$(_info 使用说明):\n"
for key in "${!usage[@]}";do
    echo -e "$(_info $key): \n\t${usage[$key]}"
done

else


if [ "$(type -t $func)" = "function" ];then 

    shift 
    if [ "$isHelp" = "-" ];then 
        #usage="${func}_usage"
        #echo -e "$func usage:\n ${!usage}"
        echo -e "$(_info usage:\\n$func)\n  ${usage[$func]}"
        echo "option help"
    else
       $func "$@"
    fi

fi

fi


